﻿#include "TreasurePart.h"
#include "Common/TableData/TreasureAwardlibCfg.h"
#include "Common/TableData/TreasureComposeCfg.h"
#include "Common/TableData/TreasureThiefCfg.h"
#include "Common/TableData/TreasureTrapCfg.h"
#include "Common/TableData/MailMailCfg.h"
#include "Common/TableData/AreaAreaCfg.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Character/monster/MonsterRefCfg.h"
#include "PackagePart.h"
#include "monster/MonsterMgr.h"
#include "npc/NpcMgr.h"
#include "Scene/MapMgr.h"
#include "Mail/GMailManager.h"
#include "Character/CreatureMgr.h"
#include "Character/HuoYueDuPart.h"
#include "Character/drop/DropMgr.h"

bool TreasurePart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB)
{
	Part::Init(pMaster, partType);

	if (pCharacterDB && pCharacterDB->has_treasuredata())
	{
		const CharacterTreasureData &treasureData = pCharacterDB->treasuredata();
		mIndex = treasureData.item_idx();
	}

	g_GetEvent()->Subscribe(this, EVENT_UNDER_ATTACK, m_pMaster->GetCid(), 0, "DeputyPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_ATTACK_SOMEBODY, m_pMaster->GetCid(), 0/*CREATURE_PLAYER*/, "DeputyPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_START_MOVE, m_pMaster->GetCid(), CREATURE_PLAYER, "DeputyPart::Init");

	return true;
}

bool TreasurePart::UnInit()
{
	g_GetEvent()->UnSubscribeAll(this);
	mIndex = 0;
	return true;
}

bool TreasurePart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	switch (cmd)
	{
	case CLIENT_TO_LOGIC_TREASURE_COMPOSE:
		Compose(data, len);
		break;
	case CLIENT_TO_LOGIC_TREASURE_ACTIVE:
		Active(data, len);
		break;
	case CLIENT_TO_LOGIC_TREASURE_UNACTIVE:
		UnActive(data, len);
		break;
	case CLIENT_TO_LOGIC_TREASURE_GET_ACTIVE:
		ActiveInfo(data, len);
		break;
	case CLIENT_TO_LOGIC_TREASURE_DIG:
		OnDig(data, len);
		break;
	default:
		break;
	}
	return true;
}

bool TreasurePart::SaveDB(CharacterDBInfo& characterDB)
{
	CharacterTreasureData *treasureData = characterDB.mutable_treasuredata();
	if (nullptr != treasureData)
	{
		treasureData->set_item_idx(mIndex);
	}
	return true;
}

void TreasurePart::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_UNDER_ATTACK:
	case EVENT_ATTACK_SOMEBODY:
	case EVENT_START_MOVE:
	{
		if (TreasureStateEnum_Begin == mTreasureState)
		{
			g_GetTimerAxis()->KillAllTimer(this);
			mTreasureState = TreasureStateEnum_Break;

			TreasureDigNotice notice;
			notice.set_state(mTreasureState);
			//notice.set_retcode(RET_TREASURE_DIGING_BREAK);
			m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		}
	}
	break;
	default:
		break;
	}
}

void TreasurePart::OnTimer(uint32_t nTimerId)
{
	switch (nTimerId)
	{
	case TreasureTimerEnum_Dig:
		{
			DigDone();
		}
		break;
	default:
		break;
	}
}

bool TreasurePart::SynOnLogin(PlayerClientInfo& playerInfo)
{
	if (mIndex <= 0)		return true;
	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)	return true;

	CItemBase* item = const_cast<CItemBase*>(pPart->GetItem(mIndex));
	if (nullptr == item || item->GetAreaId() <= 0)
		mIndex = 0;

	return true;
}

void TreasurePart::Compose(const char *data, uint32_t len)
{
	TreasureCompsReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] TreasurePart::Compose....TreasureCompsReq parse failed....");
		return;
	}
	TreasureCompsRsp rsp;
	rsp.set_retcode(RET_FAIL);

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::Compose....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		return;
	}

	CItemBase *itemBase = const_cast<CItemBase*>(pPart->GetItem(req.item_idx()));
	if (nullptr == itemBase)
	{
		LogErrFmtPrint("[logic] TreasurePart::Compose....CItemBase = nullptr item_idx = %u....", req.item_idx());
		return;
	}

	const TreasureComposeCfgMap *map = g_GetTreasureComposeCfgTable()->GetTreasureComposeCfgMap();
	if (nullptr == map)
	{
		LogErrFmtPrint(" [logic] TreasurePart::Compose....TreasureComposeCfgMap=nullptr.. failed....");
		return;
	}

	for (TreasureComposeCfgMap::const_iterator iter = map->begin(); iter != map->end(); iter++)
	{
		const TreasureComposeCfgInfo &info = iter->second;
		if (info.formula != (int32_t)itemBase->GetItemID())
		{
			continue;
		}
		if (info.formulaCount > (int32_t)itemBase->GetNum())
		{
			rsp.set_retcode(RET_TREASURE_ITEM_LACK);
			break;
		}
		SItemSourceParam sourceParam;
		sourceParam.source = S_TreasureCompose;
		sourceParam.notifySource = ENotifyType_Item_Treasure;
		if (!AddItem(info.id, 1, sourceParam))
		{
			rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
			break;
		}
		pPart->RemoveItemByIndex(req.item_idx(), info.formulaCount, sourceParam);
		rsp.set_retcode(RET_SUCCESS);
		break;
	}
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_COMPOSE, &rsp);
}

void TreasurePart::Active(const char *data, uint32_t len)
{
	TreasureActiveReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] TreasurePart::Active....TreasureCompsReq parse failed....");
		return;
	}

	TreasureActiveRsp rsp;
	rsp.set_retcode(RET_FAIL);

	if (mTreasureState == TreasureStateEnum_Begin)
	{
		rsp.set_retcode(RET_TREASURE_ILLEGAL_OPERATE);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE, &rsp);
		return;
	}

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::Active....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		return;
	}

	CItemBase *itemBase = const_cast<CItemBase*>(pPart->GetItem(req.item_idx()));
	if (nullptr == itemBase)
	{
		rsp.set_retcode(RET_TREASURE_ITEM_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE, &rsp);
		return;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemBase->GetItemID());
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::Active....nullptr == pItemCfg itemId = %d....", itemBase->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE, &rsp);
		return;
	}

	if ((int32_t)EItemFuncType::EItemFuncType_TreasureMap_NoActive != pItemCfg->functionType && (int32_t)EItemFuncType::EItemFuncType_TreasureMap_Active != pItemCfg->functionType)
	{
		LogErrFmtPrint("[logic] TreasurePart::Active....functionType is error item type = %d, itemId = %d", pItemCfg->functionType, itemBase->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE, &rsp);
		return;
	}
	
	uint32_t activeIndex = req.item_idx();
	int32_t ret = pPart->Active(activeIndex);
	if (RET_SUCCESS == ret)
	{
		mIndex = activeIndex;
		rsp.set_item_idx(activeIndex);
	}
	rsp.set_retcode(ret);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE, &rsp);
}

void TreasurePart::UnActive(const char *data, uint32_t len)
{
	TreasureUnActiveReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] TreasurePart::UnActive....TreasureUnActiveReq parse failed....");
		return;
	}

	TreasureUnActiveRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (mTreasureState == TreasureStateEnum_Begin)
	{
		rsp.set_retcode(RET_TREASURE_ILLEGAL_OPERATE);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_UNACTIVE, &rsp);
		return;
	}

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::UnActive....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_UNACTIVE, &rsp);
		return;
	}

	mIndex = 0;
	pPart->UnActive();
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_UNACTIVE, &rsp);
}

void TreasurePart::ActiveInfo(const char *data, uint32_t len)
{
	TreasureActiveInfoReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] TreasurePart::ActiveInfo....TreasureActiveInfoReq parse failed....");
		return;
	}

	TreasureActiveInfoRsp rsp;
	rsp.set_item_idx(mIndex);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_GET_ACTIVE, &rsp);
}

void TreasurePart::OnDig(const char *data, uint32_t len)
{
	TreasureDigReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....TreasureDigReq parse failed....");
		return;
	}

	TreasureDigRsp rsp;
	rsp.set_retcode(RET_FAIL);

	if (TreasureStateEnum_Begin == mTreasureState)
	{
		g_GetTimerAxis()->KillAllTimer(this);
		mTreasureState = TreasureStateEnum_Break;

		TreasureDigNotice notice;
		notice.set_state(mTreasureState);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);

		rsp.set_retcode(RET_TREASURE_DIGING_BREAK);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	const ConstantConstantCfgInfo *pDigTimeCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_TreasureDigTime);
	if (nullptr == pDigTimeCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig.....nullptr == pDigTimeCfg, id:%d ", EArg_TreasureDigTime);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	CItemBase *itemBase = const_cast<CItemBase*>(pPart->GetItem(req.item_idx()));
	if (nullptr == itemBase)
	{
		rsp.set_retcode(RET_TREASURE_ITEM_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemBase->GetItemID());
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....nullptr == pItemCfg itemId = %d....", itemBase->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	if ((int32_t)EItemFuncType::EItemFuncType_TreasureMap_NoActive != pItemCfg->functionType && (int32_t)EItemFuncType::EItemFuncType_TreasureMap_Active != pItemCfg->functionType)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....functionType is error item type = %d, itemId = %d", pItemCfg->functionType, itemBase->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	/*
	if (itemBase->GetAreaId() <= 0)
	{
		rsp.set_retcode(RET_TREASURE_ERROR_ITEM);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}*/

	const TreasureComposeCfgInfo *info = g_GetTreasureComposeCfgTable()->GetTreasureComposeCfgInfo(itemBase->GetItemID());
	if (nullptr == info)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....TreasureComposeCfgInfo = nullptr itemid = %u....", itemBase->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
		return;
	}

	g_GetTimerAxis()->KillAllTimer(this);
	g_GetTimerAxis()->SetTimer(TreasureTimerEnum_Dig, pDigTimeCfg->constantdata, this, 1);

	rsp.set_retcode(RET_SUCCESS);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_DIG, &rsp);
	
	mIndex = req.item_idx();
	mTreasureState = TreasureStateEnum_Begin;

	TreasureDigNotice notice;
	notice.set_state(mTreasureState);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
}

void TreasurePart::DigDone()
{
	g_GetTimerAxis()->KillAllTimer(this);

	TreasureDigNotice notice;
	notice.set_state(mTreasureState);

	if (mTreasureState == TreasureStateEnum_End || mTreasureState == TreasureStateEnum_Break)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone...mTreasureState = %d....", mTreasureState);
		notice.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	mTreasureState = TreasureStateEnum_End;

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		notice.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	CItemBase *itemBase = const_cast<CItemBase*>(pPart->GetItem(mIndex));
	if (nullptr == itemBase || itemBase->GetAreaId() <= 0)
	{
		notice.set_retcode(RET_TREASURE_ITEM_WAS_DELETE);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		mIndex = 0;
		return;
	}

	const TreasureComposeCfgInfo *composeCfg = g_GetTreasureComposeCfgTable()->GetTreasureComposeCfgInfo(itemBase->GetItemID());
	if (nullptr == composeCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone....TreasureComposeCfgInfo == nullptr.. failed....cfgid=%d", itemBase->GetItemID());
		notice.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	const TreasureAdventureCfgInfo* adventureInfo = g_GetTreasureMgr()->RandGame((TreasureQualityEnum)composeCfg->quality);
	if (nullptr == adventureInfo)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone....TreasureAdventureCfgInfo == nullptr.. failed....");
		notice.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	//移除物品(藏宝图)
	SItemSourceParam sourceParam;
	sourceParam.source = S_Treasure;
	sourceParam.notifySource = ENotifyType_Item_Treasure;
	pPart->RemoveItemByIndex(mIndex, 1, sourceParam);
	mIndex = 0;

	size_t size = adventureInfo->vec_advenContent.size();
	int32_t rand = Random(1000 + 1);
	int32_t temp = 0;
	int32_t gameId = 0;
	for (size_t i = 0; i < size; ++i)
	{
		temp += adventureInfo->vec_advenRand.at(i);
		if (rand <= temp)
		{
			gameId = adventureInfo->vec_advenContent.at(i);
			break;
		}
	}
	
	switch (adventureInfo->type)
	{
	case TreasureGameType_Item:
		DoGame_Item(gameId);
		notice.set_retcode(RET_TREASURE_ITEM_REFRESHOUT);
		break;
	case TreasureGameType_Task:
		AddItem(gameId, 1, sourceParam);
		notice.set_retcode(RET_TREASURE_ITEM_REFRESHOUT);
		break;
	/*case TreasureGameType_Boss::
		DoGame_Boss(gameId);
		notice.set_retcode(RET_TREASURE_MONSTER_REFRESHOUT);
		break;*/
	case TreasureGameType_Thief:
		DoGame_Thief(gameId);
		notice.set_retcode(RET_TREASURE_MONSTER_REFRESHOUT);
		break;
	case TreasureGameType_Poison:
		DoGame_Poison(gameId);
		notice.set_retcode(RET_TREASURE_POISON_REFRESHOUT);
		break;
	default:
		break;
	}

	notice.set_state(mTreasureState);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);

	TreasureEvent tEvent;
	g_GetEvent()->FireExecute(EVENT_TREASURE, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &tEvent, sizeof(TreasureEvent));

	if (adventureInfo->type == TreasureGameType_Poison)
	{
		TreasureDrugEvent drugEvent;
		g_GetEvent()->FireExecute(EVENT_TREASURE_DRUG, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &drugEvent, sizeof(TreasureDrugEvent));
	}
}

void TreasurePart::SetActiveIdx(uint32_t itemIdx)
{
	if (itemIdx > 0 && mIndex != itemIdx)
	{
		mIndex = itemIdx;
		TreasureItemIdxNotify notify;
		notify.set_item_idx(mIndex);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_ACTIVE_NOTIFY, &notify);
	}
}

void TreasurePart::GM_DigDone(uint32_t itemIdx)
{
	g_GetTimerAxis()->KillAllTimer(this);

	mTreasureState = TreasureStateEnum_End;
	TreasureDigNotice notice;
	notice.set_state(mTreasureState);

	PackagePart *pPart = dynamic_cast<PackagePart*>(m_pMaster->GetPart(PART_PACKAGE));
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] TreasurePart::OnDig....PackagePart = nullptr charid = %lu....", m_pMaster->GetCid());
		notice.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	CItemBase *itemBase = const_cast<CItemBase*>(pPart->GetItem(itemIdx));
	if (nullptr == itemBase || itemBase->GetAreaId() <= 0)
	{
		notice.set_retcode(RET_TREASURE_ITEM_WAS_DELETE);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		mIndex = 0;
		return;
	}

	const TreasureComposeCfgInfo *composeCfg = g_GetTreasureComposeCfgTable()->GetTreasureComposeCfgInfo(itemBase->GetItemID());
	if (nullptr == composeCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone....TreasureComposeCfgInfo == nullptr.. failed....cfgid=%d", itemBase->GetItemID());
		notice.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	const TreasureAdventureCfgInfo* adventureInfo = g_GetTreasureMgr()->RandGame((TreasureQualityEnum)composeCfg->quality);
	if (nullptr == adventureInfo)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone....TreasureAdventureCfgInfo == nullptr.. failed....");
		notice.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
		return;
	}

	//移除物品(藏宝图)
	SItemSourceParam sourceParam;
	sourceParam.source = S_Treasure;
	sourceParam.notifySource = ENotifyType_Item_Treasure;
	pPart->RemoveItemByIndex(mIndex, 1, sourceParam);
	mIndex = 0;

	size_t size = adventureInfo->vec_advenContent.size();
	int32_t rand = Random(1000 + 1);
	int32_t temp = 0;
	int32_t gameId = 0;
	for (size_t i = 0; i < size; ++i)
	{
		temp += adventureInfo->vec_advenRand.at(i);
		if (rand <= temp)
		{
			gameId = adventureInfo->vec_advenContent.at(i);
			break;
		}
	}

	switch (adventureInfo->type)
	{
	case TreasureGameType_Item:
		DoGame_Item(gameId);
		notice.set_retcode(RET_TREASURE_ITEM_REFRESHOUT);
		break;
	case TreasureGameType_Task:
		AddItem(gameId, 1, sourceParam);
		notice.set_retcode(RET_TREASURE_ITEM_REFRESHOUT);
		break;
		/*case TreasureGameType_Boss::
		DoGame_Boss(gameId);
		notice.set_retcode(RET_TREASURE_MONSTER_REFRESHOUT);
		break;*/
	case TreasureGameType_Thief:
		DoGame_Thief(gameId);
		notice.set_retcode(RET_TREASURE_MONSTER_REFRESHOUT);
		break;
	case TreasureGameType_Poison:
		DoGame_Poison(gameId);
		notice.set_retcode(RET_TREASURE_POISON_REFRESHOUT);
		break;
	default:
		break;
	}

	notice.set_state(mTreasureState);
	m_pMaster->SendDataToClient(EMODULE_ID_TREASURE, SERVER_TO_CLIENT_TREASURE_NOTICE, &notice);
}

void TreasurePart::DoGame_Item(int32_t gameId)
{
	const TreasureAwardlibCfgInfo *cfg = g_GetTreasureAwardlibCfgTable()->GetTreasureAwardlibCfgInfo(gameId);
	if (nullptr == cfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::DigDone....TreasureAwardlibCfgInfo == nullptr.. failed....");
		return;
	}

	VEC_INT32 boxIds;
	const VecTreasureAwardlibBoxCfg &boxVec = cfg->vecTreasureAwardlibBoxCfg;
	size_t tSize = boxVec.size();
	for (size_t i = 0; i < tSize; ++i)
	{
		const TreasureAwardlibBoxCfgInfo &boxCfg = cfg->vecTreasureAwardlibBoxCfg.at(i);
		if (boxCfg.Id > 0 && boxCfg.Rnd > 0)
		{
			int32_t tRand = Random(10000 + 1);
			if (tRand <= boxCfg.Rnd)
			{
				boxIds.push_back(boxCfg.Id);
			}
		}
	}
	if (boxIds.size() > 0)
	{
		SItemSourceParam sourceParam;
		sourceParam.source = S_Treasure;
		sourceParam.notifySource = ENotifyType_Item_Treasure;
		g_GetDropMgr()->PlayerAddBox(dynamic_cast<Player*>(m_pMaster), boxIds, sourceParam);
	}		
}

void TreasurePart::DoGame_Boss(int32_t gameId)
{
	//g_GetMonsterMgr()->CreateMonster(gameId, m_pMaster->GetSceneId(), m_pMaster->GetPos());
	//g_GetNpcMgr()->CreateNpc(gameId, m_pMaster->GetSceneId(), m_pMaster->GetPos());
}

void TreasurePart::DoGame_Thief(int32_t gameId)
{
	const TreasureThiefCfgInfo *info = g_GetTreasureThiefCfgTable()->GetTreasureThiefCfgInfo(gameId);
	if (nullptr == info)
	{
		LogErrFmtPrint("[logic] TreasurePart::DoGame_Thief....TreasureThiefCfgInfo == nullptr.. gameId=%d....", gameId);
		return;
	}

	const ConstantConstantCfgInfo *pThiefCountCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_TreasureThiefCount);
	if (nullptr == pThiefCountCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::CollectOperate.....nullptr == pThiefCountCfg, id:%u ", EArg_TreasureThiefCount);
		return;
	}

	MAP_UINT32_UINT32 mons;
	int32_t totalCount = 0;
	for (VecTreasureThiefItemCfg::const_iterator iter = info->vecTreasureThiefItemCfg.begin(); iter != info->vecTreasureThiefItemCfg.end(); iter++)
	{
		if (totalCount >= pThiefCountCfg->constantdata)
		{
			break;
		}
		if ((int32_t)Random(1000) <= (*iter).rand)
		{
			uint32_t count = Random((*iter).minNum, (*iter).maxNum);
			int32_t monsId = (*iter).id;
			mons[monsId] = count;
			totalCount += count;
		}
	}
	if (totalCount > 0)
	{
		RandMonster(mons, totalCount);
	}
}

void TreasurePart::DoGame_Poison(int32_t gameId)
{
	const TreasureTrapCfgInfo *pTrapCfg = g_GetTreasureTrapCfgTable()->GetTreasureTrapCfgInfo(gameId);
	if (nullptr == pTrapCfg)
	{
		LogErrFmtPrint("[logic] TreasurePart::DoGame_Poison....pTrapCfg == nullptr.. gameId=%d....", gameId);
		return;
	}

	Player * pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (!pPlayer)
	{
		return;
	}

	int32_t delVal = pTrapCfg->number * pPlayer->GetAttr(pTrapCfg->type) / 100.f;
	pPlayer->AddAttr(pTrapCfg->type, -1 * delVal, true);
}

bool TreasurePart::AddItem(uint32_t itemId, int32_t count, SItemSourceParam &sourceParam)
{
	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("[logic] TreasurePart::AddItem....pPackage == nullptr.. charid=%lu....", m_pMaster->GetCid());
		return false;
	}

	LIST_ITEM itemList;
	SItem item;
	item.nItemID = itemId;
	item.nNum = count;
	item.byBind = (int8_t)EBindState::EBindState_no;
	itemList.push_back(item);
	return pPackage->AddItem(itemList, sourceParam);
}

void TreasurePart::SendEmail(LIST_ITEM itemList)
{
	VEC_ITEM_PROTO_EX vecProto;
	vecProto.clear();
	SItemCond itemCond;
	g_GetDropMgr()->GetItemCond(dynamic_cast<Player*>(m_pMaster), itemCond);
	g_GetItemMgr()->SetItemProtoInfo(itemList, vecProto, itemCond);

	string strTopic = "藏宝图";
	string strContent = "挖宝获得物品！";
	g_GetGMailMgr()->SendSystemMail(m_pMaster->GetCid(), strTopic, strContent, 0, 0, 0, 0, 0, vecProto);
}

void TreasurePart::RandMonster(MAP_UINT32_UINT32 &mons, uint32_t count)
{
	uint32_t mapId = m_pMaster->GetMapId();
	Map* pMap = g_GetMapMgr()->GetMap(mapId);
	if (nullptr == pMap)
	{
		LogErrFmtPrint("[logic] TreasurePart::RandMonster....pMap == nullptr.. mapId=%u....", mapId);
		return;
	}

	//角色附近刷
	VecPoint3 vecPos;
	m_pMaster->GetScene()->FindPointLstInRect(m_pMaster->GetPos(), vecPos, 12.0f, 12.0f, count);
	if (vecPos.size() < count)
	{
		LogErrLogFmtPrint("[logic] TreasurePart::RandMonster vecPos.size() < count...count:%d", count);
		return;
	}

	uint32_t posIdx = 0;
	MonsterExtendInfo extendInfo;
	extendInfo.set_level(m_pMaster->GetAttr(C_LEVEL));
	Point3<float> dir = Point3<float>(0, 0, 1);
	for (MAP_UINT32_UINT32::iterator iter = mons.begin(); iter != mons.end(); ++iter)
	{
		if (posIdx >= count) return;
		uint32_t monsId = iter->first;
		uint32_t monsCount = iter->second;
		for (uint32_t i = 1; i <= monsCount; ++i)
		{
			MonsCreateParam createParam;
			createParam.createType = EMonsCreateType_Thief;
			g_GetCreatureMgr()->CreateMonster(monsId, m_pMaster->GetSceneId(), vecPos.at(posIdx++), createParam, dir, -1, &extendInfo);
		}
	}
}
